package org.openfidias.jdbase.model;

import java.io.Serializable;
import java.text.DecimalFormat;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.openfidias.jdbase.db.IRegister;
import org.openfidias.jdbase.db.Register;

/**
 *
 * @author atila
 */
public class AlunoDisciplina extends Register implements Serializable, Comparable, IRegister {

   private static final long serialVersionUID = 1L;
   private Aluno aluno;
   private Disciplina disciplina;

   public AlunoDisciplina() {
      this.aluno = new Aluno();
      this.disciplina = new Disciplina();
   }

   public AlunoDisciplina(String login, int codigo) {
      this.aluno = new Aluno(login);
      this.disciplina = new Disciplina(codigo);
   }

   public AlunoDisciplina(Aluno aluno, Disciplina disciplina) {
      this.aluno = aluno;
      this.disciplina = disciplina;
   }

   public Aluno getAluno() {
      return aluno;
   }

   public void setAluno(Aluno aluno) {
      this.aluno = aluno;
   }

   public Disciplina getDisciplina() {
      return disciplina;
   }

   public void setDisciplina(Disciplina disciplina) {
      this.disciplina = disciplina;
   }

   public int compareTo(Object o) {
      int compare = -1;
      if (o != null && o instanceof AlunoDisciplina) {
         AlunoDisciplina ad = (AlunoDisciplina) o;
         compare = new CompareToBuilder()
                 .append(this.aluno.getLogin(), ad.aluno.getLogin())
                 .append(this.disciplina.getCodigo(), ad.disciplina.getCodigo())
                 .toComparison();
      }
      return compare;
   }

   public String toLine() {
      StringBuilder builder = new StringBuilder();
      builder.append(new DecimalFormat("0").format(this.deleted));
      builder.append(":");
      builder.append(this.aluno.getLogin());
      builder.append(":");
      builder.append( new DecimalFormat("000").format(this.disciplina.getCodigo()) );
      builder.append(":");
      String line = StringUtils.rightPad(builder.toString(), size());
      return line;
   }

   public int size() {
      int size = Aluno.maxLogin + Disciplina.maxCodigo + 4;// <<4>> 3 from ":" and 1 for "deleted"
      return size;
   }

   public IRegister fromLine(String line) {
      String[] array = line.split(":");
      this.deleted = Short.parseShort(array[0]);
      this.aluno.setLogin(array[1]);
      this.disciplina.setCodigo(Integer.parseInt(array[2]));
      return this;
   }

   public boolean equals(String line) {
      String[] array = line.split(":");
      return isNotDeleted() && (
               this.aluno.getLogin().equals(array[1])
           &&
               new Integer(this.disciplina.getCodigo()).equals(new Integer(array[2]))
      );
   }

   public boolean equalsAtLeastOne(String line) {
      String[] array = line.split(":");
      return isNotDeleted() && (
              this.aluno.getLogin().equals(array[1])
           ||
               new Integer(this.disciplina.getCodigo()).equals(new Integer(array[2]))
      );
   }

   @Override
   public boolean equals(Object o) {

      if (!( o instanceof AlunoDisciplina )) {
         return false;
      }
      AlunoDisciplina ad = (AlunoDisciplina) o;
      return new EqualsBuilder()
              .append(this.aluno.getLogin(), ad.aluno.getLogin())
              .append(this.disciplina.getCodigo(), ad.disciplina.getCodigo())
              .isEquals();
   }

   @Override
   public int hashCode() {
      return new HashCodeBuilder()
              .append(this.aluno.getLogin())
              .append(this.disciplina.getCodigo())
              .toHashCode();
   }

   public static String headerTable() {
      StringBuilder builder = new StringBuilder();
      builder.append(rowSeparator());
      builder.append("\n|");
      builder.append(StringUtils.rightPad("Login", Aluno.maxLogin));
      builder.append("|");
      builder.append(StringUtils.rightPad("Nome", Aluno.maxNome));
      builder.append("|");
      builder.append("Matricula");
      builder.append("|");
      builder.append(StringUtils.rightPad("Código", Disciplina.maxCodigo + 3));
      builder.append("|");
      builder.append(StringUtils.rightPad("Nome", Disciplina.maxNome));
      builder.append("|");
      builder.append(StringUtils.rightPad("Curso", Disciplina.maxCurso));
      builder.append("|\n");
      builder.append(rowSeparator());
      return builder.toString();
   }

   public static String rowSeparator() {
      StringBuilder builder = new StringBuilder();
      // separator aluno
      builder.append("+");
      builder.append(StringUtils.repeat("-", Aluno.maxLogin));
      builder.append("+");
      builder.append(StringUtils.repeat("-", Aluno.maxNome));
      builder.append("+");
      builder.append(StringUtils.repeat("-", 9)); // Matricula size
      builder.append("+");
      // separator disciplina
      builder.append("+");
      builder.append(StringUtils.repeat("-", Disciplina.maxCodigo + 3));
      builder.append("+");
      builder.append(StringUtils.repeat("-", Disciplina.maxNome));
      builder.append("+");
      builder.append(StringUtils.repeat("-", Disciplina.maxCurso));
      builder.append("+");
      return builder.toString();
   }

   /**
    * Alias for rowSeparator.
    * @return
    */
   public static String footerTable() {
      return rowSeparator();
   }
}
